package git.luohao.route;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import git.luohao.entity.RouteDefinitionEntity;
import git.luohao.mapper.RouteDefinitionMapper;
import git.luohao.util.IdUtil;
import git.luohao.util.NonUtil;
import git.luohao.util.RouteUtil;
import cn.hutool.core.date.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
import org.springframework.cloud.gateway.route.CachingRouteLocator;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Component
public class RefreshRouteService implements ApplicationEventPublisherAware {

    private final Logger logger =   LoggerFactory.getLogger(RefreshRouteService.class);
    @Autowired
    ApplicationEventPublisher applicationEventPublisher;
    @Autowired
    private RouteDefinitionMapper mapper;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    //调用这个方法就可以刷新路由了
    public void refreshRoutes() {
        logger.debug("刷新路由");
        this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
    }

    public String addRoutes(RouteDefinitionEntity entity) {
        RoutePredicateHandlerMapping ma = null;
        if (validRouteEntityExist(entity)) {
            return "路由已存在";
        }
        initRouteEntity(entity);
        int insertCount = 0;
        try {
            insertCount = mapper.insert(entity);
        } catch (Exception e) {
            logger.error("添加路由规则失败", e);
            return "添加路由规则失败";
        }
        if (insertCount != 1) {
            return "添加路由规则失败";
        }
        try {
            refreshRoutes();
        } catch (Exception e) {
            logger.error("刷新路由失败", e);
        }
        return "添加并刷新路由成功";
    }

    public Boolean validRouteEntityExist(RouteDefinitionEntity entity) {
        String routeId = entity.getRouteId();
        LambdaQueryWrapper<RouteDefinitionEntity> qw = new LambdaQueryWrapper<>();
        qw.eq(RouteDefinitionEntity::getRouteId, routeId);
        Integer count = mapper.selectCount(qw);
        return count > 0;
    }

    public List<RouteDefinition> getAllRouteDefinition() {
        LambdaQueryWrapper<RouteDefinitionEntity> qw = new LambdaQueryWrapper<>();
        List<RouteDefinitionEntity> entityList = mapper.selectList(qw);
        return Optional.ofNullable(entityList)
                .map(RouteUtil::convertToRouteDefinitionList)
                .orElse(new ArrayList<>());
    }

    public void initRouteEntity(RouteDefinitionEntity entity) {
        if (NonUtil.isNon(entity)) {
            return;
        }
        entity.setId(IdUtil.getId());
        entity.setCreateTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
    }
}
